The Unofficial Newsletter of Delphi Users - by Robert Vivrette


My PALette Remembered!

The Perpetual Newbie - Log Entry #10.0

by Gary Mugford - mugford@aztec-net.com

New computers are great! Usually they mean more of everything, speed, memory, storage space … trouble! That’s trouble as in re-installing pains. Some people get around re-installing by using DiskImage or some such utility to replicate the OLD system. Seems counter-productive to me. And besides, I clean out my computer, new or not, each Spring and Fall. So, I have fallen into the habit of needing a listing of what is active in my Delphi and what’s to be discarded.

Unfortunately, there’s no handy VCL lister that I can find within Delphi itself.  I’d love one that listed each component and where it was installed from. Haven’t got the answer to the full question, but I DID produce  a program that will give me a listing I can do something with.

What follows is the basic code I used to produce the program. There are some interesting techniques for Newbies (such as buying the Registry handling tool from TurboPower [G]). But note the use of the routine to create a temporary data table (not so temp actually) and the CommaTextToStrings function that is very largely overlooked. This program DOES presume BDE, but building your own with whatever engine should be simple.

The program works for me. I haven’t tried it with Delphi 6.0 for the obvious reason of not having it yet. And I SHOULD error-proof the section for reading the Registry so that it doesn’t choke if you don’t have the key in question. But it works fine for me with just that little care to only load registry settings for the versions I actually have [G].

I include my version with this article (click here). Using BDE, it’s a tad large, even zipped up.  If any of you want to carry the ball with more portable temporary data storage and release it here to the other readers of UNDU, please feel free to do so. We’re all here to help each other out.

Here's the project stuff:
 

{---------------------------------------------------
Design a form with a dataset called TblPalette and
SourcePalette. Add a grid and a navigator for the
dataset. Add four buttons, labelled LOAD, FILL, PRINT
and EXIT. Put a memo (not a DBmemo) on the form. Create
a couple of check boxes labelled FILTER OUT HIDDEN? and
CAPITALIZE NAMES. Make both checked. Set up a radio group
with three choices, 4,5,6 defaulting to 5. I recommend
names in the text below. But you get are obviously allowed
to differ. Initially, set the table and the FILL and
PRINT buttons to inactive. GM
---------------------------------------------------------}

var
  FrmMain: TFrmMain;
const
  ChopAt = 1;

Procedure TFrmMain.FormCreate(Sender: TObject);
begin
  memoRegistryExtract.clear;  // empty the holding memo
  CreateDPaletteTable;        // create the data table if necessary
  tblPalette.active := true;  // activate the table
end;

Procedure TFrmMain.CreateDPaletteTable;
begin
  if not fileExists('DPalette.DB')  // check to see if it exists in app dir
    then with TTable.Create(Application) do
      begin
        Active := False;
        DatabaseName := ExtractFilePath(application.ExeName);
        TableName := 'DPalette';
        TableType := ttDefault;
          With FieldDefs do begin
          Add('Seq', ftInteger, 0, False); // tab sequence number
          Add('Pg', ftString, 30, False);  // tab page name
          Add('Vcl', ftString, 45, False); // component name
          // Following are check boxes for install style, After the fact edit
          Add('Dcu', ftBoolean, 0, False);
          Add('Pas', ftBoolean, 0, False);
          Add('Dpk', ftBoolean, 0, False);
          Add('BPL', ftBoolean, 0, False);
          // field for whatever you want to add after the fact
          Add('Comment', ftString, 30, False);
          end;
        // Set up a primary index and on on the component name
        with IndexDefs do begin
          Add('', 'Seq;Pg;Vcl', [ixPrimary, ixUnique]);
          Add('onVCL', 'Vcl;Pg', [ixUnique]);
          end;
        try CreateTable;
          finally Free;
          end;
        end;
end;

{----------------------------------------------------------------------------
The Registry loading section uses TurboPower's SysTools routines to load the
whole key into the memo field. The component is STRegIni. I think SysTools is
an indispensible tool for any programmer, and frankly can't live without it.
However, if you want some alternatives, a search of www.tamarack.com or of
Torry's Delphi site will surely provide you with some freeware registry
handling tools. But check out SysTools at www.turbopower.com
-----------------------------------------------------------------------------}

procedure TFrmMain.BtnLoadRegClick(Sender: TObject);
var
  k    : integer;      // lines index zero based
  KL   : TStringList;  // store a list of values in the subkey
  KReg : TSTRegIni;    // Access variable for the registry
  vNum : string[1];    // Holds the version number as a string
begin
  memoRegistryExtract.clear;  // clear memo each time button pushed
  case radiogoupVersion.itemIndex of  // get the version from the radio group
    0   : vNum := '4';
    1   : vNum := '5';
    else  vNum := '6';
    end;
  try kL := TStringList.create;
    try KReg := TSTRegIni.create(RICuser,false);
      // focus in on the target subkey
      KReg.CurSubKey := 'Software\Borland\Delphi\' + vNum + '.0\Palette';
      KReg.GetValues(KL);
      // stepped through the values list and save the value to the memo
      for k := 0 to KL.count-1 do
        // skip the section for stay on page
        if pos('.StayOnPage',kl.strings[k])=0
          then memoRegistryExtract.lines.add(kl.strings[k]);
      Application.ProcessMessages;
    finally kReg.free;
    end;
  finally KL.free;
  end;
  // Now that there is some data in the memo, allow the FillTable button to work
  BtnFillTable.enabled := true;
end;

procedure TFrmMain.BtnFillTableClick(Sender: TObject);
var
  v : integer;      // lines index zero based
  k,i : integer;    // kounters
  P,C : string;     // page, component
  E : integer;      // position of the equal sign
  SL : TStringList; // StringList to use for breaking things down
  slC : integer;    // Count of StringList of components for this page
begin
  sl := nil;
  // You could use a tblPalette.emptyTable here.
  // BUT sometimes you forget to inactivate the table while in the IDE [G]
  tblPalette.DisableControls;
  while tblPalette.RecordCount > 0
    do tblPalette.delete;
  tblPalette.enableControls;
  // disable report button while working ...
  BtnReport.enabled := false;
  // step through the memo
  V := memoRegistryExtract.Lines.Count - 1;
  for k := 0 to V
    do begin
      P := memoRegistryExtract.lines[k];
      // look for the equals sign in the value and chop it out,
      // while parsing for the page and component
      E := pos('=',P);
      C := copy(P,E+(2*ChopAt-1),length(P)-E-(2*ChopAt-1));
      P := copy(P,ChopAt,E-(2*ChopAt-1));
      if pos('.Hidden',P) <> 0  // want to be bothered with the hidden?
        then if cbFilterHidden.checked = true
          then continue
          else p := copy(P,1,pos('.Hidden',P) - 1) + '*';
      try SL := TStringList.create;
          // Now chop the component names into a list
          CommaTextToStringList(sl,c,';');
          // loop through the resulting list
          slC := sl.Count;
          for I := 0 to slC - 1
            do begin
              tblPalette.Append;
              tblPalette.fieldByName('Seq').asInteger := k + 1;
              // check the checkbox to see whether to cap names
              if cbCapNames.checked = true
                then tblPalette.FieldByName('Pg').AsString := uppercase(p)
                else tblPalette.FieldByName('Pg').AsString := p;
              ttblPalette.FieldByName('Vcl').asString := sl.strings[i];
              tblPalette.post;
              end;
        finally SL.free;
        end;
      end;
  // now it's okay to enable the Report button!
  BtnReport.enabled := true;
end;

procedure TFrmMain.BtnReportClick(Sender: TObject);
begin
  // print whatever report you design
end;

procedure TFrmMain.BtnExitClick(Sender: TObject);
begin
  close;
end;

procedure TFrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  canClose := false;
  if not (SourcePalette.state in dsEditModes)
    then CanClose := true
    else ShowMessage('You are still editing the table, please Post or Cancel');
end;


Gary Mugford
Idea Mechanic
Bramalea ON Canada